perm filename COP.MIC[ALF,DEK] blob sn#510427 filedate 1980-05-16 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00006 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	COPY FONT DISK
C00004 00003		Process an alphabet
C00006 00004		Process a character
C00009 00005		Send character data
C00010 00006		Constants and variables
C00015 ENDMK
C⊗;
;COPY FONT DISK

;Note:	The notation "addr" means word contents of addr, 'addr' means byte contents,
;	and ``addr'' means the string.

	org	4500H

COP:
	lxi	D,dm15;	Display ``LOADING...''.
	call	smd

	lxi	H,ralfdi; Read alphabet directory.
	call	dskcom
	jnz	rdfld0;	Report error if dskcom returns nonzero.

;	lhld	alfdir+3; Check access.
;	lxi	D,lessee; Floppy ID = "alfdir+3" =?= "lessee" = user ID.
;	ldax	D
;	cmp	L
;	jnz	rdfld0
;	inx	D
;	ldax	D
;	cmp	H
;	jnz	rdfld0

	lhld	alfdir+1; End of alphabet directory ← "alfdir+1" + alfdir + 3.
	lxi	D,alfdir+3
	dad	D

	lxi	D,alfdir+5;	Initialize character directory header.

ALFLP:
	push	H;	Push EAD.

	call	palph;	Process an alphabet.

	pop	H;	DE = next CDH, HL ← EAD.
	call	cmpd;	Loop while CDH < EAD.
	jc	alflp

	jmp	prmpt;	Exit.
;	Process an alphabet

PALPH:
	ldax	D;	Low byte of face number.
	call	sendc
	inx	D;	High byte of face number.
	ldax	D
	call	sendc

	inx	D;	Character directory track ← 'CDH+4'.
	inx	D
	inx	D
	ldax	D
	sta	chdtrk

	inx	D;	Push next character directory header.
	ldax	D;	NCDH = CDH + 5 + 'CDH+5' + 1.
	mov	L,A
	mvi	H,0
	dad	D
	inx	H
	push	H

	lxi	H,rchdir; Read character directory.
	call	dskcom
	jnz	rdfld0

	sub	A;	Initialize character sector and header.
	sta	chsect
	lxi	D,chrdir+3

CHLOOP:
	push	D;	Save character header.

	call	pchar;	Process a character.
	call	senchr;	Send character data.

	pop	D;	Go on to next character.
	inx	D
	inx	D
	inx	D

	lxi	H,chsect; Increment CHSECT and loop if < 129.
	inr	M
	mov	A,M
	cpi	129
	jc	chloop

	pop	D;	DE ← next CDH.
	ret
;	Process a character

PCHAR:
	ldax	D;	Check character track number for validity.
	cpi	77
	rnz

	sta	chtrak;	Track ok, put it in character track.

	lxi	H,chlink; Initialize character data pointer.
	shld	chrptr

	inx	D;	Send number of bytes in character data.
	ldax	D
	call	sendc
	inx	D
	ldax	D
	ani	00111111B
	call	sendc

	ldax	D;	Extra read for each crossing of track boundaries.
	rlc
	rlc
	ani	00000011B
	push	PSW;	Store repeat argument as loop upperbound.

	sub	A;	FOR iloop ← 0 STEP 1 UNTIL repeats.
	push	PSW

REREAD:
	lxi	H,rchar; Read character data.
	call	dskcom
	jnz	rdfld0

	pop	PSW;	If first time through then nothing to restore.
	push	PSW
	jz	rstord

	lhld	chlink;	Restore data we just had disk write over.
	lda	chlink+2; We are laying the pieces end-to-end and deleting
	xchg	;	     the extra three bytes corresponding to the track
	lhld	chrptr;      number and data length.
	mov	M,E
	inx	H
	mov	M,D
	inx	H
	mov	M,A

RSTORD:
	lhld	addr;	Update character information pointer.
	shld	chrptr

	pop	PSW;	Exit if loop upperbound reached.
	pop	B
	cmp	B
	rnc

	push	B
	inr	A;	Increment loop variable.
	push	PSW

	lhld	addr;	Store information to later write it back over
	dcx	H;	   the useless data about to overwrite it.
	mov	A,M
	sta	chlink+2
	dcx	H
	mov	D,M
	dcx	H
	mov	E,M
	shld	chrptr
	xchg
	shld	chlink

	jmp	reread
;	Send character data

SENCHR:
	lxi	D,char;	DE ← byte pointer.

SENCH1:
	ldax	D;	Send a byte.
	call	sendc

	inx	D;	Increment byte pointer and loop while < chrptr.
	lhld	chrptr
	call	cmpd
	jc	sench1

	ret


;	Error exit

RDFLD0:
	lxi	D,dm16; Error message = ``READ FAILED ON DISK 0''.
QUITIT:
	call	nfe;	Non-fatal error.
	lxi	SP,ispv; Reinitialize stack pointer to initial SP value.
	jmp	prmpt
;	Constants and variables

DM15:	db	10,'LOADING...'
DM16:	db	21,'READ FAILED ON DISK 0'

;	    	VARSE	COMWD	DISK	TRACK	SECTR	ADDR	NSCT
RALFDI:	db	1,	1,	0,	0,	131
	dw						alfdir
	db							1
RCHDIR:	db	1,	1,	0,	0,	130
	dw						chrdir
	db							1
RCHAR:	db	1,	1,	0,	0,	0
	dw						chlink
	db							1

CHDTRK	equ	rchdir+settrk;	set track of character directory.
CHSECT	equ	rchar+setsct;	set character sector.
CHTRAK	equ	rchar+settrk;	set character track.
CHRPTR	equ	rchar+setadr;	pointer into character.

ALFDIR:	ds	200H+3;	Alphabet directory.
CHRDIR:	ds	131*3;	Character directory.
CHLINK:	ds	3;	Data store for extra three bytes.
CHAR:		;	Character information.

DSKARG:	PHASE	0;	Defining disk command argument block.
SETVAR:	DB	0
SETCOM:	DB	0
SETDSK:	DB	0
SETTRK:	DB	0
SETSCT:	DB	0
SETADR:	DW	00
SETNSC:	DEPHASE
	ORG	DSKARG

; The following data addresses are required by the disk server.
	ORG	7FE4H
	DS	10;	disk server stack area
VARSE:	DB	0;	variable sector format select
	DS	9;	disk control and status area
OKWD:	DB	0;	result byte, set to 8 when initiating action
COMWD:	DB	0;	disk operation code
DISK:	DB	0;	disk number
TRACK:	DB	0;	track number
SECTR:	DB	0;	sector number
ADDR:	DW	0;	RAM address
NSCT:	DB	0;	number of sectors (0 means 256)

LESSEE	equ	001FH;	user ID.
SMD	equ	01FEH;	single message display.
NFE	equ	0110H;	nonfatal error.
ISPV	equ	7FC2H;	initial stack pointer value.
PRMPT	equ	402CH;	controlling program.
SENDC	equ	7734H;	send a character.
CMPD	equ	7734H;	double compare.
DSKCOM	equ	7734H;	disk command.
DUMP4	equ	7734H;	error exit.
MOVE	equ	7734H;	block move.

	end